package com.shfl.task.logic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.shfl.task.component.SchedulerComponent;
import com.shfl.task.exception.ApiException;
import com.shfl.task.logic.bean.TaskJob;
import com.shfl.task.logic.constants.CommonConstants;
import com.shfl.task.logic.mapper.TaskJobMapper;
import com.shfl.task.logic.model.request.AddTaskJobRequest;
import com.shfl.task.logic.model.request.CloseTaskJobRequest;
import com.shfl.task.logic.model.request.OpenTaskJobRequest;
import com.shfl.task.logic.model.response.TaskJobResponse;
import com.shfl.task.logic.service.TaskJobService;
import com.shfl.task.pagehelper.PageHelperUtils;
import com.shfl.task.pagehelper.Pageable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class TaskJobServiceImpl implements TaskJobService {

    @Autowired
    private TaskJobMapper taskJobMapper;

    @Autowired
    private SchedulerComponent schedulerComponent;

    @Override
    public List<TaskJob> findListByMap(Map<String, Object> objectMap) {
        return taskJobMapper.findListByMap(objectMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AddTaskJobRequest request) throws Exception {
        TaskJob taskJob = new TaskJob();
        BeanUtil.copyProperties(request, taskJob, false);
        checkTaskJobName(taskJob);
        taskJobMapper.insertSelective(taskJob);
        if (Objects.equals(taskJob.getJobStatus(), CommonConstants.JobStatus.OPEN.getCode())) {
            schedulerComponent.addTask(taskJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(AddTaskJobRequest request) throws Exception {
        TaskJob taskJob = taskJobMapper.selectByPrimaryKey(request.getId());
        if (taskJob == null) {
            throw new ApiException("2000");
        }
        BeanUtil.copyProperties(request, taskJob, false);
        taskJobMapper.updateByPrimaryKeySelective(taskJob);
        if (Objects.equals(taskJob.getJobStatus(), CommonConstants.JobStatus.OPEN.getCode())) {
            schedulerComponent.editCron(taskJob);
        } else {
            schedulerComponent.close(taskJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void close(CloseTaskJobRequest request) throws Exception {
        TaskJob taskJob = taskJobMapper.selectByPrimaryKey(request.getId());
        if (taskJob == null) {
            throw new ApiException("2000");
        }
        if (Objects.equals(taskJob.getJobStatus(), CommonConstants.JobStatus.CLOSE.getCode())) {
            throw new ApiException("2002");
        }
        taskJob.setJobStatus(CommonConstants.JobStatus.CLOSE.getCode());
        taskJobMapper.updateByPrimaryKeySelective(taskJob);
        schedulerComponent.close(taskJob);
    }

    @Override
    public void open(OpenTaskJobRequest request) throws Exception {
        TaskJob taskJob = taskJobMapper.selectByPrimaryKey(request.getId());
        if (taskJob == null) {
            throw new ApiException("2000");
        }
        if (Objects.equals(taskJob.getJobStatus(), CommonConstants.JobStatus.OPEN.getCode())) {
            throw new ApiException("2003");
        }
        taskJob.setJobStatus(CommonConstants.JobStatus.OPEN.getCode());
        taskJobMapper.updateByPrimaryKeySelective(taskJob);
        schedulerComponent.addTask(taskJob);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByPrimaryKeySelective(TaskJob taskJob) {
        taskJobMapper.updateByPrimaryKeySelective(taskJob);
    }

    @Override
    public PageInfo<TaskJobResponse> findPage(Pageable pageable, Map<String, Object> objectMap) {
        PageHelperUtils.startPageWithCount(pageable);
        return new PageInfo<>(taskJobMapper.findList(objectMap));

    }


    private void checkTaskJobName(TaskJob taskJob) {
        Map<String, Object> objectMap = new HashMap<>();
        objectMap.put("jobName", taskJob.getJobName());
        List<TaskJob> taskJobList = taskJobMapper.findListByMap(objectMap);
        if (CollectionUtils.isEmpty(taskJobList)) {
            return;
        }
        if (taskJobList.size() == 1 && Objects.equals(taskJob.getId(), taskJobList.get(0).getId())) {
            return;
        }
        // 存在名称相同的任务
        throw new ApiException("2001");
    }


}
